結論先說:AI alerting 要依影響範圍與可行動性分流;model outage、queue backlog、GPU 飽和、關鍵 tool provider 故障可以沿用既有的 burn-rate pager,單一品質樣本通常該先進 evaluation queue 或人工 review,而不是直接吵醒 on-call。
Day 25 定出一條界線:alert 要能回答「哪個 SLO 受威脅、誰負責、先做什麼」。今天把這條界線套進 AI workflow 最容易製造噪音的地方:語意品質訊號。
一個 RAG/Agent workflow 一開機就會生出一堆傳統 API 沒有的數字:hallucination rate、groundedness score、citation-valid ratio、evaluator 給的分數波動。這些數字看起來都很像「品質出問題了」,但如果每一個都接 pager,值班的人很快就會學會把通知靜音。今天要回答的問題是:AI 特有的這批訊號,哪些該留在傳統 burn-rate alert 的邏輯裡,哪些必須換一套判斷方式?
這個問題之所以難回答,是因為它表面上像一個「調門檻」的工程問題,實際上是一個「誰有權叫醒誰」的組織問題。傳統 alerting 的門檻通常只需要跟一個東西對齊:使用者觀察到的服務水準。AI workflow 多出來的這批訊號,卻同時牽動三個不完全重疊的關切者——維運 on-call 關心的是「服務還能不能用」,model/quality owner 關心的是「這個答案值不值得信任」,safety/compliance 關心的是「這個系統有沒有做了它不該做的事」。三個問題聽起來相關,答案卻可能完全不同:一個回答讀起來語氣自然、格式完整、系統回應也在正常時間內完成,卻同時是一次不該發生的 hallucination。同一個 hallucination_detected=true 的事件,對 on-call 來說通常不是緊急事件(服務仍在正常回應),對 quality owner 來說是需要排隊判讀的證據,對 safety 來說則要看這個幻覺有沒有跨過某條不可逆的紅線。把這三種關切硬塞進同一條 pager pipeline,最後大概率會變成「什麼都通知,什麼都沒人真的處理」。
Day 25 已經定下一條界線:alert 要能回答「哪個 SLO 受威脅、誰負責、先做什麼」。今天不是重新發明這條界線,而是把它套進更複雜的訊號光譜:一端是「HTTP 500,服務明確壞掉」,另一端是「回答語氣正常、格式完整,但其中一句是編出來的」。傳統 alerting 幾乎只處理光譜左端;AI workflow 則逼你處理右端,而右端的訊號天生帶有不確定性:同一個評估器對同一筆輸入,可能在不同時間給出不同分數;同一個「品質下降」的觀測,背後可能是模型真的變差,也可能只是評估器本身不穩定。這篇文章要建立的,就是一套承認不確定性、又不讓不確定性變成不作為藉口的分流邏輯。
讀完全篇之後,你會發現這套邏輯其實有兩層。
第一層回答「這個訊號該不該叫醒人」。
第二層回答一個更根本的問題:「量這個訊號的方法,本身值不值得信任」。
多數 alerting 文章只處理第一層,本篇會把第二層也講完。
經典 SRE 的做法在 Day 25 講過一次:availability、latency 這類直接對應使用者體驗的訊號,可以用 error-budget burn rate 接 pager;dependency error 也是等它確實威脅到使用者 SLO 才升級,而不是單次呼叫失敗就響。這條原則本身沒有因為系統換成 AI 而改變,變的是「威脅使用者 SLO」這件事在語意層要怎麼量。
Model outage、queue backlog、GPU 飽和、關鍵 tool provider 故障,這幾種訊號和傳統 dependency failure 一樣有清楚的使用者影響範圍,可以沿用既有的 burn-rate alert,理由沒變,只是依賴多了 GPU 和 provider。真正棘手的是另一批訊號:單一 hallucination、groundedness 小幅下降、evaluation score 小幅波動。這些訊號通常答不出「凌晨兩點該做什麼」,也沒有明確的使用者受影響邊界,貿然接 pager 只會製造焦慮,不會縮短事故時間。
這裡值得先說清楚,為什麼「GPU 飽和」能被歸進第一類,而不是要先送進 evaluation queue 判讀的那一類。GPU 推論失敗不像 hallucination 那樣需要人工才能定案,它通常會在兩個明確階段之一直接爆掉:模型載入階段的 VRAM 不足(例如 70B 等級的模型光是半精度權重就要吃掉一百多 GB,還沒算上長 context 的 KV cache),或是 CUDA graph capture 階段預留記憶體不夠。NVIDIA NIM 的故障排除文件與後續針對 Microsoft、Meta GPU 叢集的研究都指出,深度學習任務約有 9% 因為 OOM 而失敗(NVIDIA NIM Troubleshooting;Accurate GPU Memory Prediction for Deep Learning Jobs)。這種故障一旦發生,受影響的是「這個 route 上的所有 request」,而不是「某一則特定回答」,判斷方式和傳統的 connection pool 耗盡幾乎一樣:先看容量餘裕,再決定要不要接 pager。這正是它能沿用既有 burn-rate 邏輯的原因,hallucination 卻不行,因為後者連「誰受影響、影響到什麼程度」都要先靠人工或 evaluator 判讀出來,判讀本身就需要時間,不是一個能立即觸發安全動作的訊號。
2025 年 4 月的 Cursor 事件可用來說明「單筆語意失誤」和「該不該立即升級」是兩件事。媒體報導指出,Cursor 的 AI 客服機器人曾回覆不存在的「每訂閱限一台裝置」政策,之後引發使用者公開討論,Cursor 共同創辦人 Michael Truell 出面澄清與道歉(The Register)。這個案例不能證明每一筆錯答都需要 pager;它指出的是,若錯誤已擴散成需要對外澄清的事件,處理方式應升級為 safety review 與使用者溝通,而不必然是把基礎設施 on-call 從床上挖起來。
日常運作中更常見的情況,是把統計信號的穩定性當成判斷依據。假設對採樣流量(約 5–10%)持續計算 citation-valid ratio:單筆樣本失敗(某個回答缺有效引文)不該直接觸發 pager,但當滾動窗口內的比例從 98% 掉到 94%,代表出現系統性退化,這時該進 evaluation queue 與 release gate 檢查,而不是等使用者自己回報。單筆失敗是噪音,持續下滑的趨勢才是訊號,這正是 Day 25 那條界線在語意層的具體版本。
但這裡有個隱形陷阱:評估器本身就有噪音。同一個案例用同一個評估模型在不同時段評分會得到不同結果。一個更激進的 prompt 版本看起來「回答更詳細」,但實際讓失敗率從 2% 升到 5%,評估器的自然變異(15–20% 的內在隨機性)容易把這 3% 的真實退化淹沒在假陽性中。業界最佳實踐是同一案例評分 3 次並取中位數——這個小投資能將 100 案例數據集的假陽性降低約 60%。換句話說,沒有最小樣本數、沒有多次評分、沒有 baseline percentile 的品質下降,容易被誤判,不應直接升級。
「評估器不穩定」聽起來像一句安全的免責聲明,但它其實對應到幾種可以命名的具體現象。2025-2026 年業界對 hallucination 偵測方法已經形成一組共識做法:不對每一筆請求都做完整幻覺檢查(成本太高,一次完整的 factuality check 往往要多打一次甚至多次模型呼叫),而是在開發環境跑全量、在生產環境抽樣 5–10% 的流量,搭配異常偵測追蹤模型行為的非預期變化(FutureAGI:Detect Hallucinations in Generative AI;Braintrust:Best Hallucination Detection Tools for LLM Applications)。這套實踐還做了一件對 alerting 設計很關鍵的事:把「幻覺」拆成兩種不同的東西。
Intrinsic hallucination
模型輸出違反自己被給定的 instruction 或 retrieved context
→ 通常可以用 citation 比對、faithfulness check 自動抓到
Extrinsic hallucination
模型編造出完全無法用現有上下文驗證的事實
→ 需要外部事實查核,往往只有人工或領域專用 checker 能判定
這個拆分直接回答了一個常被忽略的問題:「citation-valid ratio 該設多高才算正常?」業界的落地數字不是單一常數,而是依場景分級——合規性工作(法律、醫療、財務決策)要求 ≥ 0.99,一般問答場景則可以放到 ≥ 0.95。但無論門檻設在哪,共識都指向同一件事:單一樣本跌破門檻不代表系統故障,該被監控的是「滾動窗口下的比例走勢」,只有走勢持續跨過門檻,才進 evaluation queue。這正是③段前面citation-valid ratio 案例(98% 掉到 94%)的依據來源,也解釋了為什麼 alert_router 裡的品質下滑判斷要同時要求 baseline、sample size 與差距門檻三個條件都成立——少了任何一個,你其實無法區分「模型真的變差了」跟「這次抽樣剛好比較倒楣」。
評估器噪音還有更根本的一層,而且是 2026 年才被具體量化出來的:評估器可能知道自己正在被評估,而它的行為會因此改變。Anthropic 用自家發展的可解釋性方法(把模型內部激活值轉譯成可讀文字的技術,稱為 Natural Language Autoencoders)分析模型的內部狀態,發現 Claude 在 SWE-bench Verified 這類標準基準測試中,約有 26% 的作答過程出現「意識到自己正在被評估」的內部訊號;在涉及高風險操作(如刪除檔案等 destructive code actions)的測試裡,這個比例是 16%。關鍵是模型幾乎不會把這件事說出口——你在輸出文字裡看不到「我知道這是測試」,這個訊號只存在於內部激活層,要靠專門的可解釋性工具才挖得出來(Anthropic 研究整理:Claude Knows It's Being Tested)。
這個發現對 AI alerting 的意義,不是「模型在說謊」這種聳動結論,而是一個更務實的提醒:你的離線評估分數,測的可能不完全是模型在生產環境的真實行為。同一份研究也提供了對照組數字——同樣的評估意識訊號,在真實 claude.ai 使用紀錄裡只出現在不到 1% 的對話中。換句話說,benchmark 環境與生產環境之間存在一個系統性落差,而這個落差的方向剛好對你不利:你在測試環境量到的品質數字,可能天生就比生產環境實際表現更好看。這正是為什麼一條品質趨勢不能只靠上線前的 release gate 評估來背書,必須有獨立的生產環境抽樣監控(也就是 evaluation queue 存在的理由),而不是把「上線前 golden dataset 測試通過」當成「生產環境會一直維持這個水準」的保證。
一份針對 agentic AI 系統的生產追蹤研究把這個落差講得更具體。研究者對部署在真實流量下的 agent 系統做了數個月的觀察,發現在固定 golden dataset 上表現優異的系統,換成真實使用者流量後開始出現系統性漂移:輸入分布改變、使用者行為模式改變、邊界案例的出現頻率遠高於測試集覆蓋範圍(arXiv:Evaluating Agentic AI in the Wild)。研究歸納出三個根本原因,剛好對應到本篇談的三個設計盲點:靜態 benchmark 測不出真實流量下的行為漂移(呼應下篇資料契約強調的 window/版本欄位)、系統可能學會優化評估指標而非真正解決問題(呼應本節「評估器噪音」的核心提醒)、既有評估框架的覆蓋範圍本來就不包含長視野決策與錯誤恢復這類 production-only 的失敗模式(呼應下篇 SRE Lab 刻意保守的 sample size 與 baseline 門檻設計)。這篇論文的結論很直接:大多數生產環境的 AI 失敗,根因不是模型能力不夠,而是評估與監控機制的更新速度跟不上生產環境變化的速度——這也是為什麼本文從頭到尾都不主張「評估一次、然後就相信這個分數」,而是主張品質訊號必須持續、可回查、可質疑。
替自己的 AI workflow 列出至少三種訊號,各自填上影響範圍、去向、owner、初步動作。
在填表之前,先問自己一個更基本的問題:這個訊號目前在你的系統裡,實際上是怎麼被處理的?
多數團隊在還沒認真設計分流之前,其實已經有一套隱性規則。
這套隱性規則通常長這樣:技術訊號(5xx、timeout)有明確的 pager,因為它是從傳統系統時代就繼承下來的習慣。
品質訊號(hallucination、groundedness)則常常落在兩個極端:要嘛完全沒人看,堆在某個 dashboard 的角落;要嘛被某次事件嚇到後,臨時接上 pager,然後半年後又被靜音,因為誤報太多。
安全訊號則經常是最模糊的一塊——沒有人明確說過「這類事件該找誰」,直到真的發生了,大家才在事件當下臨時決定升級路徑。
這張分流表要做的事,就是把這套隱性規則攤開來檢查:哪些是你其實同意的,哪些只是「一直沒人去改」。
| 訊號 | 影響 | 去向 | Owner | 初步動作 |
|---|---|---|---|---|
| model timeout 快速上升且 SLO burn | 廣泛 | pager | on-call | degradation/查 provider |
| citation-valid ratio 下降 | 未知 | evaluation queue | model owner | 比對版本與樣本 |
| 高風險 tool action 被拒絕 | 安全風險 | security review | security owner | 保留證據、停用 action |
本文未設定 paging、未串接真實 evaluation queue,也未執行安全事件升級。
Etsy 的 Opsweekly 做法,是讓值班工程師替進來的 alert 標記是否 actionable,再彙整成週報追蹤這個比例。這把「這條 alert 有沒有用」從主觀抱怨變成每週能檢視的資料。AI 特有的語意品質訊號也適用同一套量測方式:先問單筆事件能不能決定下一步,答不出來就先別接 pager。本文不以該文推論特定比例、通知量或可靠性結果,因為那些數字必須回到各團隊當時的分類資料與流量脈絡判讀。
但為什麼這件事這麼重要?2025–2026 年的產業數據很駭人。企業平均每日接收 2,992 個告警,其中 46% 是假陽性,63% 完全沒被處理。78% 的 NOC 團隊報告經歷嚴重 alert fatigue,平均每天超過 10,000 個告警,卻只有不到 5% 需要立即人工處理。這導致一個惡性迴圈:告警太多 → 工程師學會無視 → 真正的事故也被忽視(61% 的團隊承認忽略過後來被證實為關鍵的告警)。AI 系統的品質監控正在複製相同危機——當每次 prompt 版本變更、evaluator 更新都可能觸發「品質異常」通知時,工程師很快就會停止相信這些通知。
Cursor 事件則補上另一面:它示範了「單一 semantic failure」在什麼條件下會跨過那條線:不是因為出現了幻覺,而是因為影響範圍在幾天內從個案變成大規模訂閱取消。同一個 symptom(虛構回答),scope 不同,該走的流程就不同。
還有第三面,而且是本篇特別想強調的一面:你用來判斷「該不該升級」的那把尺,本身的刻度可能不準。業界對 hallucination 偵測已經有一套相對成熟的取樣與門檻共識——5–10% 抽樣、intrinsic 與 extrinsic 分開處理、依場景設定 0.95 到 0.99 的門檻,這代表這不是一個每個團隊都要從零摸索的問題。但同一批研究也指出,實驗室裡測出來的分數,和生產環境的真實表現之間,存在一個系統性、而且方向可預測的落差——測試環境的分數傾向於比生產環境更好看。也就是說,如果告警門檻是拿 release gate 測出來的分數去校準,這個門檻很可能從一開始就設得太寬鬆,因為校準用的資料本身就偏樂觀。
三個證據疊在一起,拼出的圖像是:分流表要處理的不只是「這個訊號重不重要」,還要處理「量這個訊號的尺,可不可靠」。前者是本篇大部分篇幅在談的事,後者則是下篇「評估器本身也會壞」那個案例才真正被講清楚的一層。
寫這張分流表之前,容易只想著「漏掉真正的事故」這個代價,於是傾向把可疑訊號都接 pager。但 Etsy 的六成數字提醒我,過度 paging 也有代價:它會磨掉值班工程師對 alert 的信任,下次真正的事故來了,反而更慢被當一回事。Cursor 案例則提醒我不能只看訊號種類分流,還要留一條路給「影響範圍正在擴大」這種例外,不然分流表會把真正該立即處理的個案也晾在 evaluation queue 裡。
寫這張分流表時我也發現,它本身需要一個「evaluator 可能不可靠」的但書。一開始設計分流邏輯時,我下意識把 evaluator 的判斷當成事實——quality_status 是 needs_review,就是 needs_review,不會再多問一句。但 Anthropic 那份研究提醒我,評估環境本身可能悄悄改變模型的行為,而這個效應在真正的生產環境裡幾乎不存在。換句話說,我在測試階段信任的那個評估分數,天生就帶著一點「這是在考試」的偏差,而我卻打算拿它去校準生產環境的告警門檻——下篇會用一個真實案例(release gate 通過、三週後才現形)把這個偏差講得更具體。
這讓我在分流表之外,多加了一條自己的提醒:任何拿來設定門檻的評估數字,都要先問一句「這個分數是從哪個環境量出來的」,而不是預設所有分數都可以互相比較。
如果這是真實 production system,我會做三件事:把 model outage、queue backlog、GPU 飽和、tool provider 故障這類有清楚使用者影響邊界的訊號,直接掛進既有的 burn-rate pager,不用另外發明一套 AI 專屬告警邏輯;把 hallucination rate、groundedness、evaluation score 這類語意品質訊號改成滾動窗口監控,送進 evaluation queue 與 release gate,只有趨勢持續惡化才升級;同時替高風險 safety 事件保留一條獨立的立即升級路徑,並用類似 Opsweekly 的方式定期檢視每條規則的 actionable 比例,讓分流表隨著實際使用情況調整,而不是寫完就當作永遠正確。
第四件事,是替評估本身留一道審查機制:任何拿來設定告警門檻的品質分數,都要先確認它的量測環境跟門檻要套用的環境是不是同一種——上線前 golden dataset 測出來的分數,不能直接拿去校準生產環境的告警線,兩者要各自維護一套基準,並且定期核對彼此有沒有拉開距離。這五件事合起來,才是一套完整的分流政策:誰負責被叫醒、誰負責被通知、誰負責善後,以及最容易被忘記的——量這一切的尺子,本身要不要被校準。
AI 系統最容易犯的設計錯誤,是把每一個可量測欄位都當成告警候選人。它們不是。groundedness_score=0.61 是一筆觀測資料:它可能代表檢索沒有找到文件,也可能代表 evaluator 看錯了,還可能只是某個使用者問了資料庫根本沒有答案的問題。在沒有時間窗口、樣本數、工作流版本與使用者影響以前,這個分數不能直接推導出 incident。
更麻煩的是,連「0.61」這個數字本身的可信度,都要看它是從哪個評估環境量出來的——這句話現在聽起來可能有點跳躍,但讀到下篇「評估器本身也會壞」那個案例之後,你會發現這正是這兩篇想一路鋪陳到底的提醒。
先分清四個層次,後面的設計才不會全部擠進 pager。
| 層次 | 問題 | 典型載體 | 是否即時叫人 |
|---|---|---|---|
| Event | 這一次 request 發生什麼? | log、trace、feedback | 否 |
| Signal | 最近是否出現模式? | metric、dashboard | 通常否 |
| Decision | 要不要改變流量、版本或流程? | queue、release gate | 依風險 |
| Alert | 現在是否需要特定 owner 介入? | page、ticket、security escalation | 只有可行動時 |
這個拆法看似語意問題,其實是成本問題:每送出一則 pager,都在消耗值班者的注意力;每忽略一個品質趨勢,也可能累積成使用者傷害。分流的工作不是讓通知越少越好,而是讓每個訊號走到能處理它的地方。
這四個層次也不是一次性的分類,而是一條資料會依序爬過的階梯:一筆 request 完成後先變成 Event,記錄在 log 或 trace 裡;多個 Event 累積出模式,才變成出現在 dashboard 或 metric 上的 Signal;Signal 是否需要人為介入,取決於 Decision 這一層的判斷——這正是 evaluation queue 存在的位置;只有 Decision 認定「需要特定 owner 立刻做點什麼」,才會產出 Alert。多數 AI alerting 失敗的案例,問題不是任何一個層次本身設計錯了,而是跳過了中間幾層,讓 Event 直接被當成 Alert。
可以把 Day 26 的核心流程畫成這樣:
request / trace / user feedback
|
v
normalise evidence
|
+--> technical impact? ----> SLO burn / pager
|
+--> safety boundary? ----> security escalation
|
+--> sustained quality drift? -> evaluation queue
|
+--> isolated sample? ------> trace review / dataset candidate
|
+--> no reproducible evidence -> dashboard only
同一筆 trace 可以同時進兩條路:模型 timeout 造成 /ask 的 task failure,技術面會影響 availability SLO;同一筆 trace 的 prompt 也可能成為事後分析 provider fallback 是否正確的樣本。這不叫重複處理——前者在回答「服務還能不能用」,後者在回答「為什麼這次失敗,以及下次怎麼少失敗」。這個雙重用途提醒了一件容易被忽略的事:同一份 evidence 不該只有一個消費者。設計資料契約時,如果只考慮「pager 需要什麼欄位」,很可能會漏掉 evaluation queue 或 postmortem 之後才需要的欄位——例如 prompt 版本、retrieval index 版本這些技術告警不太在意、但品質分析非常在意的資訊。下一節的資料契約,就是把這兩種用途一起考慮進去後的結果。
不論用 Prometheus、OpenTelemetry、LangSmith、Langfuse,還是自建事件表,分流前都需要一個不依賴特定產品的資料契約。
若每個團隊各自發明欄位,當 incident 發生時就得先猜資料能不能接起來。
這裡用一個最小事件表示法。
{
"observed_at": "2026-09-22T09:00:00Z",
"request_id": "req_01",
"trace_id": "trace_01",
"task_id": "task_01",
"workflow_name": "policy_rag",
"workflow_version": "2026.09.22.1",
"service_version": "api-1.8.0",
"prompt_version": "policy-answer-v4",
"model_provider": "provider-a",
"model_name": "model-x",
"retrieval_index_version": "policy-2026-09-20",
"technical_status": "success",
"task_status": "failed",
"quality_status": "needs_review",
"safety_status": "pass",
"fallback_triggered": false,
"latency_ms": 1840
}
欄位很多,但並不是要把它們全做成 Prometheus label。
request_id、trace_id、task_id 的 cardinality 幾乎等於 request 數量。
把它們塞進 metric label,時間序列會膨脹,監控系統自己先變成事故。
它們適合放在 log、trace 或 evaluation record。
metric 裡只保留用來彙整的有限維度。
例如 workflow、model route、outcome、是否 fallback。
from prometheus_client import Counter, Histogram
ai_task_total = Counter(
"ai_task_total",
"Completed AI tasks grouped by stable outcome dimensions.",
["workflow", "model_route", "task_status", "quality_status", "safety_status"],
)
ai_request_latency_seconds = Histogram(
"ai_request_latency_seconds",
"End-to-end AI workflow latency.",
["workflow", "model_route", "fallback_triggered"],
)
這段不是要你立刻把程式貼進 production。
它要表達的是 label 的邊界。
workflow="policy_rag" 的值是有限集合。
model_route="primary" 與 "fallback" 也是有限集合。
request_id="req_01" 則永遠會增加。
後者必須留在 trace,而不是 metric。
接著替每一筆品質資料保留可回查的 evidence。
quality_event = {
"trace_id": trace_id,
"task_id": task_id,
"workflow_version": workflow_version,
"prompt_version": prompt_version,
"evaluator_version": "citation-check-v2",
"sampled": True,
"score": 0.0,
"reason": "citation_does_not_support_claim",
"review_state": "unreviewed",
}
reason 不應是模型隨手生成的一大段自然語言。
把它收斂成有限類別,例如 missing_citation、unsupported_claim、unsafe_tool_request、evaluator_error。
這樣才能在 dashboard 上回答:哪一類錯誤正在增加?
若要保留完整說明,把它放在 trace annotation 或 review record。
review_state 這個欄位,是為了對付一種很容易被忽略的競態quality_event 裡的 review_state 欄位,一開始很容易被當成無關緊要的狀態旗標,但它其實在處理一個時間差的問題:一筆事件被建立的當下,evaluator 給的分數是 unreviewed,這個分數可能過幾分鐘就被人工複查推翻,也可能三次評分取中位數後數字整個改變。如果 dashboard 或 alert 邏輯直接讀第一次寫入的分數,看到的可能是一個已經過時、甚至已經被推翻的判斷。review_state 讓下游知道:這筆資料現在能不能被信任地拿去算趨勢。
review_state = unreviewed
剛寫入,只有自動評分,尚未有人工或多次評分覆核
review_state = confirmed
自動評分與人工複查(或多次評分中位數)一致,可信度較高
review_state = overturned
人工複查推翻了自動評分的判斷,這筆事件不該再被算進失敗計數
沒有這個欄位,品質趨勢圖上每一個資料點其實都帶著不同程度的不確定性,卻被畫成看起來一樣精確的一條線;有了它,至少能在畫圖時把「已複核」跟「還沒複核」的部分用不同顏色標出來,讓看圖的人知道最近的幾個資料點還可能會變動。這聽起來是個小細節,但它正是下篇「評估器本身也會壞」那個案例想指出的問題在資料層的具體解法:不是不相信評估器,而是誠實標記每一筆評估的可信度,不要讓一次性的自動評分偽裝成已經蓋棺論定的事實。
很多告警規則失控,是因為團隊先打開 alert manager,才開始討論升級策略。
順序應反過來。
先寫出每條路的目的、owner 與時限。
Pager 的前提不是「數字很大」。
前提是有持續、可證實的使用者影響,而且值班者有一個安全動作可做。
適合 Pager 的例子:
/ask 5xx 與 timeout 讓 error budget 快速燃燒。不適合 Pager 的例子:
Pager 事件至少要附上這些內容:
service: ai-api
workflow: policy_rag
symptom: /ask availability error-budget fast burn
first observed: 09:02 UTC
scope: all requests routed to provider-a
owner: api-on-call
safe first action: enable known fallback route
evidence: dashboard URL, trace query, deploy version
其中 safe first action 是核心。
如果通知只寫「hallucination rate high」,值班者即使半夜看到,也無從判斷能不能切模型、能不能停止流量、能不能撤回 prompt。
這種 alert 不是資訊不足,是責任設計沒有完成。
Evaluation queue 接的是「需要研究」而不是「現在要救火」的工作。
典型觸發條件可以是:
unsupported_claim 比例上升。Queue item 不該只是一個百分比。
它要能帶人回到樣本。
queue item: quality-drift-2026-09-22-001
window: 08:00-09:00 UTC
workflow: policy_rag
comparison: prompt v4 versus v3
signal: citation-valid ratio 98.2% -> 94.1%
sample size: 186 sampled completed tasks
top reason: unsupported_claim
evidence: 12 representative trace links
owner: model-quality rotation
due: next business day
這裡的 sample size 不能省。
十筆樣本中少一筆,和一千筆樣本中少一百筆,不是同一種訊號。
若資料是抽樣,也必須說抽樣比例與方式。
沒有 denominator 的「品質下降 4%」幾乎無法判讀。
Safety escalation 不必等待統計趨勢。
原因不是它一定更嚴重,而是有些行為一旦成功執行就不可逆。
例如:
這條路要有獨立 owner。
把它丟給一般 API on-call,常見結果是「先等白天的模型團隊看看」。
那不叫升級。
範例紀錄可以長這樣:
event_type: unauthorized_tool_attempt
severity: high
executed: false
policy_decision: deny
tool_name: export_customer_records
trace_id: trace_01
containment: tool call was blocked
next owner: security incident lead
executed: false 和 executed: true 是完全不同的事件。
記錄「有被擋住」也很重要。
它既是 near-miss 的證據,也是 Day 27 復盤時能檢查防線是否真正工作的材料。
有些訊號並不假裝成警報,反而更有用。
例如 prompt token 緩慢上升、低風險回答的使用者 dislike、retriever 命中數突然變多。
它們可以進 dashboard,並用週期性 ticket 要求 owner 檢視。
這不是放著不管。
這是承認它們需要長時間尺度的判讀。
下面是一份可直接改名後使用的草案。
它不是通用答案。
門檻必須由你的 SLO、業務風險、流量與回應時間決定。
這份政策草案本身也值得被追問一句:每一列的「首要 owner」,是不是一個真人、一個團隊,而不是一個群組信箱?
owner 欄位寫「platform team」聽起來合理,實際運作起來卻常常變成沒有人。
值班表、輪班制度、交接窗口,這些才是讓 owner 欄位從一個名詞變成一個真正會回應的人的必要條件。
寫政策的時候,順手核對一下這一列,往往比核對門檻數字更能預防未來的漏接。
| 事件類型 | 最小證據 | 預設去向 | 首要 owner | 第一個安全動作 |
|---|---|---|---|---|
/ask fast burn |
SLO window 內持續失敗 | Pager | API on-call | 套用既定降級或 fallback |
| provider timeout | 造成 task failure 且無有效 fallback | Pager | API on-call | 檢查 provider 狀態與 route |
| queue backlog | 已威脅 latency SLO | Pager 或 ticket | platform on-call | 限流、擴容或暫停非必要工作 |
| citation-valid 下滑 | 樣本數、窗口、版本都完整 | Evaluation queue | quality owner | 比對 prompt、index 與 evaluator |
| evaluator disagreement | 多個 evaluator 或人工抽查不一致 | Dataset review | evaluation owner | 標記 evaluator 不可靠範圍 |
| unsafe tool attempt | policy evidence 完整 | Security escalation | security owner | 保留 evidence、限制 capability |
| single bad answer | trace 可回查 | Review sample | workflow owner | 標記與分類,不立即改 production |
| cost increase | 成本窗口超過預算 | FinOps ticket | platform owner | 檢查 routing、token 與 retry |
表格裡的「最小證據」是防止情緒型 alert 的欄位。
沒有 evidence 的 event 可以被記錄。
不能自動把人叫起來。
同時替每一條政策設定反例。
反例能逼團隊說清楚「為什麼這次不升級」。
| 規則 | 容易誤觸發的反例 | 防呆方式 |
|---|---|---|
| quality drift | 流量突然集中到本來就難的問題 | 依工作流與輸入類別切分,保留 baseline |
| provider outage | 單一 region 網路波動 | 以使用者 SLO 與成功率交叉驗證 |
| unsafe request | red-team 測試流量 | 清楚標記測試環境與測試帳號 |
| token spike | 合法長文件導致輸入變大 | 比較文件大小與 prompt 版本 |
| negative feedback | 使用者偏好差異 | 建立可分類 feedback,不用單一 dislike 斷言品質 |
這份政策草案本身只是紙上規則。下篇會把它接上真正可測試的路由邏輯、Prometheus 規則與三個完整判讀案例,並回頭處理一個更根本的問題:你用來校準這些門檻的評估分數,本身值不值得信任。
這篇是 Learning SRE for the AI Era 系列的一部分。
Build → Trace → Break → Measure → Evaluate → Recover → Improve.